home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / mach / ds3100.md / machDis.c < prev    next >
C/C++ Source or Header  |  1990-09-21  |  5KB  |  225 lines

  1. /* machDis.c -
  2.  *
  3.  *         This contains the routine which disassembles an instruction to find
  4.  *    the target.
  5.  *
  6.  *    Copyright (C) 1989 Digital Equipment Corporation.
  7.  *    Permission to use, copy, modify, and distribute this software and
  8.  *    its documentation for any purpose and without fee is hereby granted,
  9.  *    provided that the above copyright notice appears in all copies.  
  10.  *    Digital Equipment Corporation makes no representations about the
  11.  *    suitability of this software for any purpose.  It is provided "as is"
  12.  *    without express or implied warranty.
  13.  */
  14.  
  15. #ifndef lint
  16. static char rcsid[] = "$Header: /sprite/src/kernel/mach/ds3100.md/RCS/machDis.c,v 9.2 90/09/21 15:51:29 mgbaker Exp $ SPRITE (Berkeley)";
  17. #endif not lint
  18.  
  19. #include "sprite.h"
  20. #include "mach.h"
  21.  
  22. /*
  23.  * Define the three basic types of instruction formats.
  24.  */
  25. typedef struct {
  26.   unsigned imm: 16;
  27.   unsigned f2: 5;
  28.   unsigned f1: 5;
  29.   unsigned op: 6;
  30. } ITypeFmt;
  31.  
  32. typedef struct {
  33.   unsigned target: 26;
  34.   unsigned op: 6;
  35. } JTypeFmt;
  36.  
  37. typedef struct {
  38.   unsigned funct: 6;
  39.   unsigned f4: 5;
  40.   unsigned f3: 5;
  41.   unsigned f2: 5;
  42.   unsigned f1: 5;
  43.   unsigned op: 6;
  44. } RTypeFmt;
  45.  
  46. /*
  47.  * Opcodes of the branch instructions.
  48.  */
  49. #define OP_SPECIAL    0x00
  50. #define OP_BCOND    0x01
  51. #define OP_J        0x02
  52. #define    OP_JAL        0x03
  53. #define OP_BEQ        0x04
  54. #define OP_BNE        0x05
  55. #define OP_BLEZ        0x06
  56. #define OP_BGTZ        0x07
  57.  
  58. /*
  59.  * Branch subops of the special opcode.
  60.  */
  61. #define OP_JR        0x08
  62. #define OP_JALR        0x09
  63.  
  64. /*
  65.  * Sub-ops for OP_BCOND code.
  66.  */
  67. #define OP_BLTZ        0x00
  68. #define OP_BGEZ        0x01
  69. #define OP_BLTZAL    0x10
  70. #define OP_BGEZAL    0x11
  71.  
  72. /*
  73.  * Coprocessor branch masks.
  74.  */
  75. #define COPz_BC_MASK    0x1a
  76. #define COPz_BC        0x08
  77. #define COPz_BC_TF_MASK    0x01
  78. #define COPz_BC_TRUE    0x01
  79. #define COPz_BC_FALSE    0x00
  80.  
  81. /*
  82.  * Coprocessor 1 operation.
  83.  */
  84. #define OP_COP_1    0x11
  85.  
  86. static unsigned *GetBranchDest _ARGS_((ITypeFmt *iInstPtr));
  87.  
  88. unsigned *
  89. MachEmulateBranch(regsPtr, instPC, fpcCSR, allowNonBranch)
  90.     unsigned    *regsPtr;
  91.     Address    instPC;
  92.     unsigned    fpcCSR;
  93.     Boolean    allowNonBranch;
  94. {
  95.     JTypeFmt    *jInstPtr;
  96.     RTypeFmt    *rInstPtr;
  97.     ITypeFmt    *iInstPtr;
  98.     unsigned    *retAddr;
  99.  
  100. #ifdef notdef
  101.     printf("regsPtr=%x PC=%x Inst=%x fpcCsr=%x\n", regsPtr, instPC,
  102.                            *(unsigned *)instPC, fpcCSR);
  103. #endif
  104.  
  105.     jInstPtr = (JTypeFmt *)instPC;
  106.     rInstPtr = (RTypeFmt *)instPC;
  107.     iInstPtr = (ITypeFmt *)instPC;
  108.  
  109.     switch ((int)jInstPtr->op) {
  110.         case OP_SPECIAL:
  111.         switch ((int)rInstPtr->funct) {
  112.         case OP_JR:
  113.         case OP_JALR:
  114.             retAddr = (unsigned *)regsPtr[rInstPtr->f1];
  115.             break;
  116.         default:
  117.             if (allowNonBranch) {
  118.             retAddr = (unsigned *)(instPC + 4);
  119.             } else {
  120.             panic("MachEmulateBranch: Non-branch\n");
  121.             }
  122.             break;
  123.         }
  124.         break;
  125.         case OP_BCOND:
  126.         switch ((int)iInstPtr->f2) {
  127.         case OP_BLTZ:
  128.         case OP_BLTZAL:
  129.             if ((int)(regsPtr[rInstPtr->f1]) < 0) { 
  130.             retAddr = GetBranchDest(iInstPtr);
  131.             } else {
  132.             retAddr = (unsigned *) (instPC + 8);
  133.             }
  134.             break;
  135.         case OP_BGEZAL:
  136.         case OP_BGEZ:
  137.             if ((int)(regsPtr[rInstPtr->f1]) >= 0) { 
  138.             retAddr = GetBranchDest(iInstPtr);
  139.             } else {
  140.             retAddr = (unsigned *) (instPC + 8);
  141.             }
  142.             break;
  143.         default:
  144.             panic("MachEmulateBranch: Bad branch cond\n");
  145.             break;
  146.         }
  147.         break;
  148.         case OP_J:
  149.         case OP_JAL:
  150.         retAddr = (unsigned *) ((jInstPtr->target << 2) | 
  151.                    ((unsigned)instPC & 0xF0000000));
  152.         break;
  153.         break;
  154.         case OP_BEQ:
  155.         if (regsPtr[rInstPtr->f1] == 
  156.             regsPtr[rInstPtr->f2]) {
  157.         retAddr = GetBranchDest(iInstPtr);
  158.         } else {
  159.         retAddr = (unsigned *) (instPC + 8);
  160.         }
  161.         break;
  162.         case OP_BNE:
  163.         if (regsPtr[rInstPtr->f1] != 
  164.             regsPtr[rInstPtr->f2]) {
  165.         retAddr = GetBranchDest(iInstPtr);
  166.         } else {
  167.         retAddr = (unsigned *) (instPC + 8);
  168.         }
  169.         break;
  170.         case OP_BLEZ:
  171.         if ((int)(regsPtr[rInstPtr->f1]) <= 0) { 
  172.         retAddr = GetBranchDest(iInstPtr);
  173.         } else {
  174.         retAddr = (unsigned *) (instPC + 8);
  175.         }
  176.         break;
  177.         case OP_BGTZ:
  178.         if ((int)(regsPtr[rInstPtr->f1]) > 0) { 
  179.         retAddr = GetBranchDest(iInstPtr);
  180.         } else {
  181.         retAddr = (unsigned *) (instPC + 8);
  182.         }
  183.         break;
  184.     case OP_COP_1: {
  185.         Boolean    condition;
  186.  
  187.         if ((rInstPtr->f1 & COPz_BC_MASK) == COPz_BC) {
  188.         if ((rInstPtr->f2 & COPz_BC_TF_MASK) == COPz_BC_TRUE) {
  189.             condition = fpcCSR & MACH_FPC_COND_BIT;
  190.         } else {
  191.             condition = !(fpcCSR & MACH_FPC_COND_BIT);
  192.         }
  193.         if (condition) {
  194.             retAddr = GetBranchDest(iInstPtr);
  195.         } else {
  196.             retAddr = (unsigned *) (instPC + 8);
  197.         }
  198.         } else if (allowNonBranch) {
  199.         retAddr = (unsigned *)(instPC + 4);
  200.         } else {
  201.         panic("MachEmulateBranch: Bad coproc branch instruction\n");
  202.         }
  203.         break;
  204.     }
  205.     default:
  206.         if (allowNonBranch) {
  207.         retAddr = (unsigned *)(instPC + 4);
  208.         } else {
  209.         panic("MachEmulateBranch: Non-branch instruction\n");
  210.         }
  211.         break;
  212.     }
  213. #ifdef notdef
  214.     printf("Target addr=%x\n", retAddr);
  215. #endif
  216.     return(retAddr);
  217. }
  218.  
  219. static unsigned *
  220. GetBranchDest(iInstPtr)
  221.     ITypeFmt    *iInstPtr;
  222. {
  223.     return((unsigned *)((Address)iInstPtr + 4 + ((short)iInstPtr->imm << 2)));
  224. }
  225.